/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.xo;

import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author william
 */
public class XOBase<E> {

    protected Logger log = LoggerFactory.getLogger(XOObject.class);
    protected E m;
    protected SimpleDateFormat xo_date_fmt = new SimpleDateFormat("yyyyMMddHHmmss");

    public E _m() {
        return m;
    }

    public String json() {
        return m.toString();
    }

    public String quote(String string) {
        if (string == null || string.length() == 0) {
            return "\"\"";
        }

        char b;
        char c = 0;
        String hhhh;
        int i;
        int len = string.length();
        StringBuilder sb = new StringBuilder(len + 4);
        sb.append('"');
        for (i = 0; i < len; i += 1) {
            b = c;
            c = string.charAt(i);
            switch (c) {
                case '\\':
                case '"':
                    sb.append('\\');
                    sb.append(c);
                    break;
                case '\b':
                    sb.append("\\b");
                    break;
                case '\t':
                    sb.append("\\t");
                    break;
                case '\n':
                    sb.append("\\n");
                    break;
                case '\f':
                    sb.append("\\f");
                    break;
                case '\r':
                    sb.append("\\r");
                    break;
                default:
                    if (c < ' ' || (c >= '\u0080' && c < '\u00a0')
                            || (c >= '\u2000' && c < '\u2100')) {
                        hhhh = "000" + Integer.toHexString(c);
                        sb.append("\\u").append(hhhh.substring(hhhh.length() - 4));
                    } else {
                        sb.append(c);
                    }
            }
        }
        sb.append('"');
        return sb.toString();
    }

    public String valueToString(Object value) {

        if (value == null || value.equals("null")) {
            return "null";
        }

        if (value instanceof Number) {
            return numberToString((Number) value);
        }

        if (value instanceof Boolean) {
            return value.toString();
        }
        
          if (value instanceof Date) {
            return "$date@"+xo_date_fmt.format((Date)value);
        }
        
        if(value instanceof IXOArray){
            return ((IXOArray)value).json();
        }
        
        if(value instanceof IXOObject){
            return ((IXOObject)value).json();
        }
        
        if (value instanceof Map) {
            return new XOObject((Map) value).json();
        }

        if (value instanceof Collection) {
            return new XOArray((Collection) value).toString();
        }

        if (value.getClass().isArray()) {
            return new XOArray(value).toString();
        }

        return quote(value.toString());

    }

    public String numberToString(Number number) {
        if (number == null) {
            throw new RuntimeException("Null pointer");
        }

        String string = number.toString();
        if (string.indexOf('.') > 0 && string.indexOf('e') < 0
                && string.indexOf('E') < 0) {
            while (string.endsWith("0")) {
                string = string.substring(0, string.length() - 1);
            }
            if (string.endsWith(".")) {
                string = string.substring(0, string.length() - 1);
            }
        }
        return string;
    }
    
}
